package com.myzl.coal.client;

import com.myzl.coal.domain.Device;
import com.myzl.coal.domain.DeviceProtocol;
import com.myzl.coal.domain.RealTimeData;
import com.myzl.coal.service.IDeviceProtocolService;
import com.myzl.coal.service.IDeviceService;
import com.myzl.coal.service.IRealTimeDataService;
import com.myzl.common.core.domain.entity.SysDictData;
import com.myzl.common.utils.DictUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @ClassName CacheData
 * @Author wzb
 * @Date 2022/12/23 13:44
 * @Description
 */
@Component
@Data
@Slf4j
public class CacheData {
    @Lazy
    @Autowired
    private  IDeviceService deviceService;
    private final IRealTimeDataService realTimeDataService;
    private final IDeviceProtocolService deviceProtocolService;

    private static Map<String, RealTimeData> realTimeDataMap = new HashMap<>();
    private static Map<Integer, DeviceProtocol> protocolMap = new HashMap<>();
    private static Map<String, SysDictData> dictMap = new HashMap<>();
    private static Map<Integer, Device> deviceIds = new HashMap<>();
    private static Map<String, Integer> urls = new HashMap<>();

    public static Map<String, SysDictData> getStringSysDictDataMap() {
        if (dictMap.isEmpty()) {
            List<SysDictData> radar_function = DictUtils.getDictCache("radar_function");
            List<SysDictData> plc_function = DictUtils.getDictCache("plc_function");
            List<SysDictData> sieve_radar_function = DictUtils.getDictCache("sieve_radar_function");
            List<SysDictData> binocular_radar_function = DictUtils.getDictCache("binocular_radar_function");

            List<SysDictData> allType = new ArrayList<>();
            if (!CollectionUtils.isEmpty(plc_function)) {
                allType.addAll(plc_function);
            }
            if (!CollectionUtils.isEmpty(radar_function)) {
                allType.addAll(radar_function);
            }
            if (!CollectionUtils.isEmpty(sieve_radar_function)) {
                allType.addAll(sieve_radar_function);
            }
            if (!CollectionUtils.isEmpty(binocular_radar_function)) {
                allType.addAll(binocular_radar_function);
            }
            dictMap = allType.stream().collect(Collectors.toMap(SysDictData::getDictValue, Function.identity()));
        }

        return dictMap;
    }

    public Device getDevice(Integer deviceId) {
        Device device;
        if (deviceIds.containsKey(deviceId)){
            device=deviceIds.get(deviceId);
        }else {
            device = deviceService.cacheDeviceById(deviceId);
            deviceIds.put(deviceId,device);
            urls.put(BaseHandler.getKey(device.getIp(),device.getPort()),deviceId);
        }
        return device;
    }
    public Integer getDeviceId(String ip,Integer port) {
        Integer deviceId;
        String key = BaseHandler.getKey(ip, port);
        if (urls.containsKey(key)){
            deviceId=urls.get(key);
        }else {
            Device device = deviceService.cacheDeviceByUrl(ip,port);
            if (device==null){
                log.info("不存在ip:{},port:{}的设备",ip,port);
                return null;
            }
            deviceIds.put(device.getId(),device);
            urls.put(BaseHandler.getKey(device.getIp(),device.getPort()),device.getId());
            deviceId=device.getId();
        }
        return deviceId;
    }

    public Double getRealTimeData(Integer deviceId, Integer dictValue) {

        String key = deviceId + "-" + dictValue;
        if (!realTimeDataMap.containsKey(key)) {
            RealTimeData realTimeData = realTimeDataService.queryByDictValue(deviceId, dictValue);
            if (realTimeData == null) {
                log.info("设备数据未初始化,deviceId:{},dictValue{}", deviceId,dictValue);
                return 0D;
            } else {
                realTimeDataMap.put(key, realTimeData);
            }
        }
        return Double.valueOf(realTimeDataMap.get(key).getDataValue());
    }


    public DeviceProtocol getDeviceProtocolMap(Integer deviceType) {
        if(!protocolMap.containsKey(deviceType)){
            DeviceProtocol deviceProtocol = deviceProtocolService.cacheByDeviceType(deviceType);
            protocolMap.put(deviceType,deviceProtocol);
        }
        return protocolMap.get(deviceType);
    }


    @CacheEvict(value = {"device","deviceProtocol"},allEntries = true,beforeInvocation=true)
    public void refresh() {
        clear();
    }

    public static void clear() {
        realTimeDataMap.clear();
        protocolMap.clear();
        dictMap.clear();
        deviceIds.clear();
        urls.clear();
    }

//    @Scheduled(fixedDelay = 24 * 60 * 60 * 1000)
//    public void test() {
//        refresh();
//    }

}
